package com.chenl.provider.DEMOS.Spring.Spring事务相关;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.chenl.provider.DEMOS.日志相关.全局日志.WebLog;
import com.chenl.provider.DTO.entity.MyStudent;
import com.chenl.provider.mapper.Service.StuServiceImpl;
import com.chenl.provider.mapper.StuMapper;
import com.chenl.provider.service.StudentServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;


@Slf4j
@RestController
@RequestMapping("/transController")
public class SpringTransController {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("123");
        list.add("345");
        list.add("456");
        System.out.println(JSONObject.toJSONString(list));
    }

    //    public static void method(Map<String,String> parentMap,String parentId){
//        Map<String,Map>resMap=new HashMap<>();//
//        String s = parentMap.get(parentId);//s=第一批子的字符串
//        List<String> list = Arrays.asList(s.split(","));
//        for (String item : list) {//遍历第一批子集合
//            String temp=item;
//            while (parentMap.get(temp)!=null){
//                Map map  = new HashMap<>();
//                String s2 = parentMap.get(temp);
//                if (parentMap.get(temp)!=null){
//                    List<String> list2 = Arrays.asList(s2.split(","));
//                    resMap.put()
//                }
//            }
//
//            resMap.put(item,map);
//
//        }
//
//    }
    @Autowired
    StudentServiceImpl studentService;
    @Autowired
    StuMapper stuMapper;
    @Autowired
    private DataSourceTransactionManager dataSourceTransactionManager;
    @Autowired
    private TransactionDefinition transactionDefinition;

    @Autowired
    ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;
    @Autowired
    private SpringTransService springTransService;

    @Autowired
    TransactionTemplate transactionTemplate;

    /**
     * 声明式事务DEMO
     * https://blog.csdn.net/zdp1128lj315/article/details/137969041?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522BDA0A255-4520-4628-977D-B0B4453B7F33%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=BDA0A255-4520-4628-977D-B0B4453B7F33&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-2-137969041-null-null.142^v100^pc_search_result_base9&utm_term=transactionTemplate.execute&spm=1018.2226.3001.4187
     */
    public void addStudent() {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                try {
                    // ....  业务代码
//                    studentMapper.insert(s1);
                    int i = 1 / 0;
//                    studentMapper.insert(s2);
                } catch (Exception e) {
                    //回滚
                    transactionStatus.setRollbackOnly();
                }

            }
        });
    }


        /**
         * 在事务完成后可以做一些额外事情，比如把mq的发送放进去
         * @return
         * @throws InterruptedException
         */
        @WebLog
        //可以通过注解控制
//    @Transactional
        @PostMapping("/test")
        public String test () throws InterruptedException {
            MyStudent student = new MyStudent();
            student.setStuName("张三1");
            student.setStuAge("22");
            student.setPhone("17720885142");
            springTransService.save();
//        studentService.save(student);
            // 1.使用封装的工具类
            TransactionUtils.doAfterTransaction(() -> {
                log.info("事务提交了,发送成功MQ~~然后开始睡觉");
                try {
                    TimeUnit.SECONDS.sleep(5);
                    log.info("事务提交了,发送成功MQ~~睡觉结束");
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }, () -> {
                log.info("事务回滚了,发送失败MQ~~");
                try {
                    TimeUnit.SECONDS.sleep(5);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            });
            System.out.println(1 / 0);
            // 2.直接使用事务同步器
  /*      TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
            @Override
            public void afterCompletion(int status) {
                if (status==STATUS_COMMITTED){
                    log.info("事务提交了,发送成功MQ");
                }else if (status==STATUS_ROLLED_BACK){
                    log.info("事务回滚了,发送失败MQ");
                }
            }
        });*/
            System.out.println("666");
            //3.使用事务监听器
//        TransactionThreadLocal.set(new HashMap<String,Object>(){{put("年龄",23);}});
//        applicationEventPublisher.publishEvent("肥猪一个");
//        System.out.println(1/0);
//        Thread.sleep(10000);
            return "ok";
        }

        /**
         * 手动开启和提交事务
         * @return
         * @throws InterruptedException
         */
        @PostMapping("/test2")
        public String test2 () throws InterruptedException {
            TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);//手动开启事务
            MyStudent student = new MyStudent();
            student.setStuName("张三1");
            student.setStuAge("22");
            student.setPhone("17720885142");
//        this.save(student);
            dataSourceTransactionManager.commit(transactionStatus);//手动提交事务
            return "ok";
        }
        @Autowired
        StuServiceImpl stuService;
        @PostMapping("/test3")
        public String test3 () throws InterruptedException {
            List<MyStudent> list = buildVos();
            MyStudent myStudent = new MyStudent();
            myStudent.setPhone("1772088");
            myStudent.setStuName("张三");
            myStudent.setStuAge("23");
            myStudent.setModifyTime(LocalDateTime.now().plusDays(1L).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            stuService.save(myStudent);
            return "ok";
        }

        private List<MyStudent> buildVos () {
            List<MyStudent> list = new ArrayList<>();
            for (int i = 0; i < 10000; i++) {
                MyStudent student = new MyStudent();
                student.setStuName("张三");
                student.setStuAge("2" + i);
                student.setPhone("1772088514" + i);
                list.add(student);
            }
            return list;
        }

    }